
class Vue{

    constructor(obj){

        this.$el = obj.el;
        this.$data = obj.data;

        // 订阅msg。
        let msgObserver = new Observer();
        // id为p01的标签订阅了msg值的变化
        msgObserver.addSubscriber(function(newVal){
            document.querySelector("#p01").innerHTML = newVal;
        })

        // id为p02的标签订阅了msg值的变化
        msgObserver.addSubscriber(function(newVal){
            document.querySelector("#p02").innerHTML = newVal;
        })

        // id为p03的标签订阅了msg值的变化
        msgObserver.addSubscriber(function(newVal){
            document.querySelector("#p03").innerHTML = newVal;
        })

        // 1、把data中的数据，挂载到vue对象上
        for(let key in obj.data){
            
            let val = obj.data[key];
            // 给vue的对象增加属性
            Object.defineProperty(this,key,{
                set:function(newVal){
                    console.log(key+"被改了",newVal);
                    if(newVal!=val){
                        val = newVal;
                        // 发布
                        if(key==="msg"){
                            msgObserver.publish(newVal);
                        }
                    }
                },
                get:function(){
                    return val;
                }
            })
        }


        // 把数据渲染在页面上
        this.render()

    }

    render(){

        let root = document.querySelector(this.$el);

        let htmlStr = root.innerHTML;

        // htmlStr = htmlStr.replaceAll("{{msg}}",this.msg);
        for(let key in this.$data){
            htmlStr = htmlStr.replaceAll("{{"+key+"}}",this[key]);
        }

        root.innerHTML = htmlStr;

    }

}


// 观察者模式的代码：

class Observer{
    constructor(){
        // 定义一个数组，保存所有的订阅者
        this.arr = [];
    }

    // 订阅
    addSubscriber(cb){
        this.arr.push(cb);
    }

    // 发布
    publish(what){
        this.arr.forEach(item=>item(what));
    }

}